package com.smart.community.region.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.smart.community.commons.result.Result;
import com.smart.community.region.entity.PropertyHouseType;
import com.smart.community.region.service.IPropertyHouseTypeService;
import com.smart.community.region.dto.PropertyHouseTypeQueryDTO;
import com.smart.community.region.dto.PropertyHouseTypeCreateDTO;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 物业公司户型表控制器
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/region/house-types")
@Tag(name = "户型配置管理", description = "物业公司户型配置相关接口")
public class PropertyHouseTypeController {

    @Autowired
    private IPropertyHouseTypeService propertyHouseTypeService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 创建户型配置
     * 
     * @param createDTO 户型创建DTO
     * @return 创建结果
     * @throws Exception 统一异常
     */
    @PostMapping
    @Operation(summary = "创建户型配置", description = "创建新的户型配置")
    @ApiLog(
        logTitle = "创建户型配置",
        logType = 2,
        moduleName = "区域管理",
        operationType = ApiLogOperationType.ADD
    )
    public Result<Boolean> createHouseType(@Parameter(description = "户型创建信息") @Valid @RequestBody PropertyHouseTypeCreateDTO createDTO) throws Exception {
        log.info("创建户型配置，户型名称：{}，物业公司ID列表：{}", createDTO.getHouseTypeName(), createDTO.getPropertyCompanyIds());
        
        // 转换为实体对象
        PropertyHouseType houseType = new PropertyHouseType();
        houseType.setHouseTypeName(createDTO.getHouseTypeName());
        houseType.setTotalArea(createDTO.getTotalArea());
        houseType.setUsableArea(createDTO.getUsableArea());
        houseType.setPublicArea(createDTO.getPublicArea());
        houseType.setEfficiencyRate(createDTO.getEfficiencyRate());
        houseType.setBedroomCount(createDTO.getBedroomCount());
        houseType.setMasterBedroomCount(createDTO.getMasterBedroomCount());
        houseType.setSecondaryBedroomCount(createDTO.getSecondaryBedroomCount());
        houseType.setChildrenRoomCount(createDTO.getChildrenRoomCount());
        houseType.setLivingRoomCount(createDTO.getLivingRoomCount());
        houseType.setDiningRoomCount(createDTO.getDiningRoomCount());
        houseType.setKitchenCount(createDTO.getKitchenCount());
        houseType.setBathroomCount(createDTO.getBathroomCount());
        houseType.setMasterBathroomCount(createDTO.getMasterBathroomCount());
        houseType.setPublicBathroomCount(createDTO.getPublicBathroomCount());
        houseType.setGuestBathroomCount(createDTO.getGuestBathroomCount());
        houseType.setStudyRoomCount(createDTO.getStudyRoomCount());
        houseType.setStorageRoomCount(createDTO.getStorageRoomCount());
        houseType.setCloakroomCount(createDTO.getCloakroomCount());
        houseType.setEntranceGardenCount(createDTO.getEntranceGardenCount());
        houseType.setOrientation(createDTO.getOrientation());
        houseType.setMasterBedroomOrientation(createDTO.getMasterBedroomOrientation());
        houseType.setLivingRoomOrientation(createDTO.getLivingRoomOrientation());
        houseType.setFloorPosition(createDTO.getFloorPosition());
        houseType.setHasGarden(createDTO.getHasGarden());
        houseType.setHasTerrace(createDTO.getHasTerrace());
        houseType.setHasAttic(createDTO.getHasAttic());
        houseType.setIsSquare(createDTO.getIsSquare());
        houseType.setHasIrregularSpace(createDTO.getHasIrregularSpace());
        houseType.setIsTransparent(createDTO.getIsTransparent());
        houseType.setIsAllBright(createDTO.getIsAllBright());
        houseType.setHasDynamicStaticSeparation(createDTO.getHasDynamicStaticSeparation());
        houseType.setHasWetDrySeparation(createDTO.getHasWetDrySeparation());
        houseType.setBalconyCount(createDTO.getBalconyCount());
        houseType.setBalconyType(createDTO.getBalconyType());
        houseType.setBalconyStyle(createDTO.getBalconyStyle());
        houseType.setBayWindowCount(createDTO.getBayWindowCount());
        houseType.setBayWindowType(createDTO.getBayWindowType());
        houseType.setKitchenHasBalcony(createDTO.getKitchenHasBalcony());
        houseType.setBathroomHasBathtub(createDTO.getBathroomHasBathtub());
        houseType.setBathroomHasSeparation(createDTO.getBathroomHasSeparation());
        houseType.setBathroomHasWindow(createDTO.getBathroomHasWindow());
        houseType.setFloorHeight(createDTO.getFloorHeight());
        houseType.setNetHeight(createDTO.getNetHeight());
        houseType.setHasLoft(createDTO.getHasLoft());
        houseType.setHasDuplex(createDTO.getHasDuplex());
        houseType.setCanModify(createDTO.getCanModify());
        houseType.setHasGiftArea(createDTO.getHasGiftArea());
        houseType.setGiftAreaDesc(createDTO.getGiftAreaDesc());
        houseType.setFloorPlanType(createDTO.getFloorPlanType());
        houseType.setFloorPlanStatus(createDTO.getFloorPlanStatus());
        houseType.setFloorPlanUrl(createDTO.getFloorPlanUrl());
        houseType.setAdvantageTags(convertListToJsonString(createDTO.getAdvantageTags()));
        houseType.setSuitableCrowd(createDTO.getSuitableCrowd());
        houseType.setRemark(createDTO.getRemark());
        houseType.setStatus(createDTO.getStatus() != null ? createDTO.getStatus() : 1); // 默认启用
        
        // 批量创建户型（支持多物业公司）
        boolean success = propertyHouseTypeService.createHouseTypeForCompanies(houseType, createDTO.getPropertyCompanyIds());
        
        return Result.success(success);
    }

    /**
     * 将List<String>转换为JSON字符串
     * 
     * @param list 字符串列表
     * @return JSON字符串
     */
    private String convertListToJsonString(List<String> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(list);
        } catch (JsonProcessingException e) {
            log.warn("转换List<String>为JSON字符串失败", e);
            return String.join(",", list);
        }
    }

    /**
     * 根据物业公司ID查询户型列表
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 户型列表
     * @throws Exception 统一异常
     */
    @GetMapping("/property-company/{propertyCompanyId}")
    @Operation(summary = "根据物业公司ID查询户型列表", description = "根据物业公司ID查询户型配置列表")
    public Result<List<PropertyHouseType>> getByPropertyCompanyId(
            @Parameter(description = "物业公司ID") @PathVariable Long propertyCompanyId) throws Exception {
        log.info("根据物业公司ID查询户型列表，物业公司ID：{}", propertyCompanyId);
        
        List<PropertyHouseType> houseTypes = propertyHouseTypeService.getByPropertyCompanyId(propertyCompanyId);
        return Result.success(houseTypes);
    }

    /**
     * 分页查询户型列表
     * 
     * @param queryDTO 查询条件
     * @return 分页结果
     * @throws Exception 统一异常
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询户型列表", description = "根据条件分页查询户型配置列表")
    public Result<IPage<PropertyHouseType>> getPage(@Parameter(description = "查询条件") PropertyHouseTypeQueryDTO queryDTO) throws Exception {
        log.info("分页查询户型列表，物业公司ID：{}，户型名称：{}", queryDTO.getPropertyCompanyId(), queryDTO.getHouseTypeName());
        
        IPage<PropertyHouseType> result = propertyHouseTypeService.getPage(queryDTO);
        return Result.success(result);
    }

    /**
     * 根据ID获取户型详情
     * 
     * @param id 户型ID
     * @return 户型详情
     * @throws Exception 统一异常
     */
    @GetMapping("/{id}")
    @Operation(summary = "根据ID获取户型详情", description = "根据户型ID获取户型配置详细信息")
    public Result<PropertyHouseType> getHouseTypeById(@Parameter(description = "户型ID") @PathVariable Long id) throws Exception {
        log.info("根据ID获取户型详情，户型ID：{}", id);
        
        PropertyHouseType houseType = propertyHouseTypeService.getHouseTypeById(id);
        if (houseType == null) {
            return Result.error("户型不存在");
        }
        return Result.success(houseType);
    }

    /**
     * 更新户型配置
     * 
     * @param id 户型ID
     * @param createDTO 户型更新DTO
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新户型配置", description = "更新指定户型配置信息")
    @ApiLog(
        logTitle = "更新户型配置",
        logType = 2,
        moduleName = "区域管理",
        operationType = ApiLogOperationType.UPDATE
    )
    public Result<Boolean> updateHouseType(@Parameter(description = "户型ID") @PathVariable Long id, 
                                          @Parameter(description = "户型更新信息") @Valid @RequestBody PropertyHouseTypeCreateDTO createDTO) throws Exception {
        log.info("更新户型配置，户型ID：{}，户型名称：{}", id, createDTO.getHouseTypeName());
        
        // 转换为实体对象
        PropertyHouseType houseType = new PropertyHouseType();
        houseType.setId(id);
        houseType.setHouseTypeName(createDTO.getHouseTypeName());
        houseType.setTotalArea(createDTO.getTotalArea());
        houseType.setUsableArea(createDTO.getUsableArea());
        houseType.setPublicArea(createDTO.getPublicArea());
        houseType.setEfficiencyRate(createDTO.getEfficiencyRate());
        houseType.setBedroomCount(createDTO.getBedroomCount());
        houseType.setMasterBedroomCount(createDTO.getMasterBedroomCount());
        houseType.setSecondaryBedroomCount(createDTO.getSecondaryBedroomCount());
        houseType.setChildrenRoomCount(createDTO.getChildrenRoomCount());
        houseType.setLivingRoomCount(createDTO.getLivingRoomCount());
        houseType.setDiningRoomCount(createDTO.getDiningRoomCount());
        houseType.setKitchenCount(createDTO.getKitchenCount());
        houseType.setBathroomCount(createDTO.getBathroomCount());
        houseType.setMasterBathroomCount(createDTO.getMasterBathroomCount());
        houseType.setPublicBathroomCount(createDTO.getPublicBathroomCount());
        houseType.setGuestBathroomCount(createDTO.getGuestBathroomCount());
        houseType.setStudyRoomCount(createDTO.getStudyRoomCount());
        houseType.setStorageRoomCount(createDTO.getStorageRoomCount());
        houseType.setCloakroomCount(createDTO.getCloakroomCount());
        houseType.setEntranceGardenCount(createDTO.getEntranceGardenCount());
        houseType.setOrientation(createDTO.getOrientation());
        houseType.setMasterBedroomOrientation(createDTO.getMasterBedroomOrientation());
        houseType.setLivingRoomOrientation(createDTO.getLivingRoomOrientation());
        houseType.setFloorPosition(createDTO.getFloorPosition());
        houseType.setHasGarden(createDTO.getHasGarden());
        houseType.setHasTerrace(createDTO.getHasTerrace());
        houseType.setHasAttic(createDTO.getHasAttic());
        houseType.setIsSquare(createDTO.getIsSquare());
        houseType.setHasIrregularSpace(createDTO.getHasIrregularSpace());
        houseType.setIsTransparent(createDTO.getIsTransparent());
        houseType.setIsAllBright(createDTO.getIsAllBright());
        houseType.setHasDynamicStaticSeparation(createDTO.getHasDynamicStaticSeparation());
        houseType.setHasWetDrySeparation(createDTO.getHasWetDrySeparation());
        houseType.setBalconyCount(createDTO.getBalconyCount());
        houseType.setBalconyType(createDTO.getBalconyType());
        houseType.setBalconyStyle(createDTO.getBalconyStyle());
        houseType.setBayWindowCount(createDTO.getBayWindowCount());
        houseType.setBayWindowType(createDTO.getBayWindowType());
        houseType.setKitchenHasBalcony(createDTO.getKitchenHasBalcony());
        houseType.setBathroomHasBathtub(createDTO.getBathroomHasBathtub());
        houseType.setBathroomHasSeparation(createDTO.getBathroomHasSeparation());
        houseType.setBathroomHasWindow(createDTO.getBathroomHasWindow());
        houseType.setFloorHeight(createDTO.getFloorHeight());
        houseType.setNetHeight(createDTO.getNetHeight());
        houseType.setHasLoft(createDTO.getHasLoft());
        houseType.setHasDuplex(createDTO.getHasDuplex());
        houseType.setCanModify(createDTO.getCanModify());
        houseType.setHasGiftArea(createDTO.getHasGiftArea());
        houseType.setGiftAreaDesc(createDTO.getGiftAreaDesc());
        houseType.setFloorPlanType(createDTO.getFloorPlanType());
        houseType.setFloorPlanStatus(createDTO.getFloorPlanStatus());
        houseType.setFloorPlanUrl(createDTO.getFloorPlanUrl());
        houseType.setAdvantageTags(convertListToJsonString(createDTO.getAdvantageTags()));
        houseType.setSuitableCrowd(createDTO.getSuitableCrowd());
        houseType.setRemark(createDTO.getRemark());
        houseType.setStatus(createDTO.getStatus() != null ? createDTO.getStatus() : 1);
        
        boolean success = propertyHouseTypeService.updateHouseType(houseType);
        
        return Result.success(success);
    }

    /**
     * 删除户型配置
     * 
     * @param id 户型ID
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除户型配置", description = "删除指定户型配置")
    @ApiLog(
        logTitle = "删除户型配置",
        logType = 2,
        moduleName = "区域管理",
        operationType = ApiLogOperationType.DELETE
    )
    public Result<Boolean> deleteHouseType(@Parameter(description = "户型ID") @PathVariable Long id) throws Exception {
        log.info("删除户型配置，户型ID：{}", id);
        
        boolean success = propertyHouseTypeService.deleteHouseType(id);
        
        return Result.success(success);
    }

    /**
     * 更新户型状态
     * 
     * @param id 户型ID
     * @param statusMap 状态信息
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @PutMapping("/{id}/status")
    @Operation(summary = "更新户型状态", description = "更新指定户型的状态")
    @ApiLog(
        logTitle = "更新户型状态",
        logType = 2,
        moduleName = "区域管理",
        operationType = ApiLogOperationType.UPDATE
    )
    public Result<Boolean> updateHouseTypeStatus(@Parameter(description = "户型ID") @PathVariable Long id,
                                                @Parameter(description = "状态信息") @RequestBody Map<String, Object> statusMap) throws Exception {
        log.info("更新户型状态，户型ID：{}，状态：{}", id, statusMap.get("status"));
        
        Integer status = (Integer) statusMap.get("status");
        if (status == null) {
            return Result.error("状态参数不能为空");
        }
        
        boolean success = propertyHouseTypeService.updateStatus(id, status);
        
        return Result.success(success);
    }

    /**
     * 检查户型名称是否已存在
     * 
     * @param houseTypeName 户型名称
     * @param propertyCompanyId 物业公司ID
     * @param excludeId 排除的户型ID
     * @return 是否存在
     * @throws Exception 统一异常
     */
    @GetMapping("/check-name")
    @Operation(summary = "检查户型名称是否已存在", description = "检查指定物业公司下户型名称是否已存在")
    public Result<Boolean> checkHouseTypeName(@Parameter(description = "户型名称") @RequestParam String houseTypeName,
                                             @Parameter(description = "物业公司ID") @RequestParam Long propertyCompanyId,
                                             @Parameter(description = "排除的户型ID") @RequestParam(required = false) Long excludeId) throws Exception {
        log.info("检查户型名称是否已存在，户型名称：{}，物业公司ID：{}，排除ID：{}", houseTypeName, propertyCompanyId, excludeId);
        
        boolean exists = propertyHouseTypeService.checkHouseTypeNameExists(houseTypeName, propertyCompanyId, excludeId);
        return Result.success(exists);
    }
}
